package com.tudouji.project.bill.service.impl;

import com.flow.service.pojo.ResultParam;
import com.flow.service.pojo.result.FlowResult;
import com.flow.service.process.service.impl.FlowProcessProxy;
import com.tudouji.common.enums.WhoutformTypeEnums;
import com.tudouji.common.exception.CustomException;
import com.tudouji.common.utils.DateUtils;
import com.tudouji.common.utils.IdUtils;
import com.tudouji.common.utils.SecurityUtils;
import com.tudouji.common.utils.poi.ExcelTempUtil;
import com.tudouji.framework.task.MeituanDataProcessUtil;
import com.tudouji.framework.web.domain.AjaxResult;
import com.tudouji.project.bill.domain.*;
import com.tudouji.project.bill.mapper.*;
import com.tudouji.project.bill.service.IWhoutformService;
import com.tudouji.project.flow.utils.FlowProcessUtil;
import com.tudouji.project.harvest.domain.Freightorder;
import com.tudouji.project.harvest.domain.Weighlist;
import com.tudouji.project.harvest.mapper.FreightorderMapper;
import com.tudouji.project.harvest.mapper.WeighlistMapper;
import com.tudouji.project.organization.domain.Organization;
import com.tudouji.project.organization.mapper.OrganizationMapper;
import com.tudouji.project.permission.service.ISalespermissionService;
import com.tudouji.project.produce.domain.*;
import com.tudouji.project.produce.mapper.PickinglistMapper;
import com.tudouji.project.produce.mapper.PickinglistitemMapper;
import com.tudouji.project.produce.mapper.ProduceplanMapper;
import com.tudouji.project.produce.mapper.ScrapapplyMapper;
import com.tudouji.project.produce.service.IPickinglistitemService;
import com.tudouji.project.product.domain.Productinfo;
import com.tudouji.project.product.domain.Salesspecification;
import com.tudouji.project.product.service.IProductinfoService;
import com.tudouji.project.product.service.ISalesspecificationService;
import com.tudouji.project.repository.domain.RptStoreanalysis;
import com.tudouji.project.repository.mapper.RptStoreanalysisMapper;
import com.tudouji.project.store.domain.Stockunit;
import com.tudouji.project.store.domain.Storehouseroom;
import com.tudouji.project.store.domain.Storeroom;
import com.tudouji.project.store.mapper.StorehouseroomMapper;
import com.tudouji.project.store.mapper.StoreroomMapper;
import com.tudouji.project.store.service.IStockunitService;
import com.tudouji.project.system.domain.SysUser;
import com.tudouji.project.system.mapper.SysUserMapper;
import com.tudouji.project.system.service.ISysConfigService;
import com.tudouji.project.system.service.impl.BusinesscodeServiceImpl;
import com.tudouji.project.wlinfo.domain.Wlinfoitem;
import com.tudouji.project.wlinfo.mapper.WlinfoMapper;
import com.tudouji.project.wlinfo.mapper.WlinfoitemMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 出库单Service业务层处理
 *
 * @author wf
 * @date 2021-01-12
 */
@Slf4j
@Service
public class WhoutformServiceImpl implements IWhoutformService {
    @Autowired
    private WhoutformMapper whoutformMapper;
    @Autowired
    private WhoutformitemMapper whoutformitemMapper;
    @Autowired
    private ISalespermissionService permissionService;
    @Autowired
    private ISalesspecificationService salesSpecificationService;
    @Autowired
    private IStockunitService stockunitService;
    @Autowired
    private BusinesscodeServiceImpl codeService;
    @Autowired
    private StorehouseroomMapper storehouseroomMapper;
    @Autowired
    private StoreroomMapper storeroomMapper;
    @Autowired
    private WhinfoServiceImpl whinfoService;
    @Autowired
    private WhinforecordServiceImpl whinforecordService;
    @Autowired
    private RptStoreanalysisMapper rptStoreanalysisMapper;
    @Autowired
    private TransferapplyitemServiceImpl transferapplyitemService;
    @Autowired
    private TransferapplyServiceImpl transferapplyService;
    @Autowired
    private FlowProcessUtil processUtils;
    @Autowired
    private FlowProcessProxy flowProcessProxy;
    @Autowired
    private SellformMapper sellformMapper;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private SellitemMapper sellitemMapper;
    @Autowired
    private SellitemServiceImpl sellitemService;
    @Autowired
    private SellformServiceImpl sellformService;
    @Autowired
    private SellspitemMapper sellspitemMapper;
    @Autowired
    private PickinglistMapper pickinglistMapper;
    @Autowired
    private ScrapapplyMapper scrapapplyMapper;
    @Autowired
    private FreightorderMapper freightorderMapper;
    @Autowired
    private IPickinglistitemService pickinglistitemService;
    @Autowired
    private PickinglistitemMapper pickinglistitemMapper;
    @Autowired
    private ProduceplanMapper produceplanMapper;
    @Autowired
    private WeighlistMapper weighlistMapper;
    @Autowired
    private WlinfoitemMapper wlinfoitemMapper;
    @Autowired
    private WlinfoMapper wlinfoMapper;
    @Autowired
    private ExcelTempUtil excelTempUtil;
    @Autowired
    private IProductinfoService productinfoMapper;
    @Autowired
    private OrganizationMapper organizationMapper;


    @Resource
    private SysUserMapper sysUserMapper;

    public static final String KG = "toKg";
    public static final String T = "toT";

    /**
     * 查询出库单
     *
     * @param autoid 出库单ID
     * @return 出库单
     */
    @Override
    public Whoutform selectWhoutformById(Long autoid) {
        return whoutformMapper.selectWhoutformById(autoid);
    }

    /**
     * 查询出库单列表
     *
     * @param whoutform 出库单
     * @return 出库单
     */
    @Override
    public List<Whoutform> selectWhoutformList(Whoutform whoutform) {
        return whoutformMapper.selectWhoutformList(whoutform);
    }

    /**
     * 新增出库单
     *
     * @param whoutform 出库单
     * @return 结果
     */
    @Override
    public int insertWhoutform(Whoutform whoutform) {
        if (whoutform.getCreatetime() != null){
            whoutform.setCreatetime(DateUtils.getNowDate());
        }
        return whoutformMapper.insertWhoutform(whoutform);
    }

    /**
     * 修改出库单
     *
     * @param whoutform 出库单
     * @return 结果
     */
    @Override
    public int updateWhoutform(Whoutform whoutform) {
        return whoutformMapper.updateWhoutform(whoutform);
    }

    /**
     * 批量删除出库单
     *
     * @param autoids 需要删除的出库单ID
     * @return 结果
     */
    @Override
    public int deleteWhoutformByIds(Long[] autoids) {
        return whoutformMapper.deleteWhoutformByIds(autoids);
    }

    /**
     * 删除出库单信息
     *
     * @param autoid 出库单ID
     * @return 结果
     */
    @Override
    public int deleteWhoutformById(Long autoid) {
        return whoutformMapper.deleteWhoutformById(autoid);
    }

    /**
     * 出库单列表查询
     */
    @Override
    public List<Whoutform> findWhoutformList(Whoutform whoutform) {

        return this.whoutformMapper.findWhoutformList(whoutform);

    }

    @Override
    public String saveTransferWhout(List<Whoutformitem> items, Whoutform form) {
        return saveWhoutform(items, form);
    }

    @Override
    public List<Whoutform> findDetail(Whoutform whoutform) {
        return whoutformMapper.findDetail(whoutform);
    }

    @Override
    public Whoutform selectWhoutformByOrderId(String orderId) {
        return whoutformMapper.selectWhoutformByOrderId(orderId);
    }

    @Override
    public List<Whoutform> selectWhoutformsHistory() {
        return whoutformMapper.selectWhoutformsHistory();
    }

    @Override
    public Whoutform selectWhoutformByGuid(String whoutid) {
        return whoutformMapper.selectWhoutformByGuid(whoutid);
    }

    public String saveWhoutform(List<Whoutformitem> items, Whoutform outform) {
        // 生成编码
        String guid = IdUtils.fastSimpleUUID();
        outform.setGuid(guid);
        outform.setWhoutcode(codeService.getCode("7"));
        outform.setOuttime(new Date());
        outform.setCreatetime(DateUtils.getNowDate());
        whoutformMapper.insertWhoutform(outform);
        // 保存明细
        BigDecimal weight = new BigDecimal(0);
        for (Whoutformitem item : items) {
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setSrguid(outform.getSrguid());
            item.setWhoutid(guid);
            item.setOrgguid(outform.getOrgguid());
            item.setOrgname(outform.getOrgname());

            Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
            if (house.getShrtype() == 1) {//如果是原料库 则统一设置 原料规格出库
                Salesspecification spe = new Salesspecification();
                spe.setProductguid(item.getProductguid());
                spe.setBaseFlag(1);
                spe = salesSpecificationService.selectSalesspecificationList(spe).get(0);
                item.setSpguid(spe.getGuid());
                item.setSpename(spe.getName());
            }

            item.setItemguid(item.getScrapitemid());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whoutformitemMapper.insertWhoutformitem(item);
            weight = weight.add(item.getWeight());

            // 更新库存
            Whinfo info;
            if (outform.getOuttype() == 7) {// 农户库存调整查询
                info = whinfoService.getFarmerWhinfo(item.getProductguid(), item.getSrguid(), item.getShrguid());
            } else {
//				if (house.getShrtype() == 1) {// 1-原材料库，2-产成品库 3-废品库（不合格品库）
//					info = infoService.getWhinfo(outform.getOrgguid(), item.getProductguid(), item.getSrguid(),
//							item.getShrguid());
//				} else {// 产品
                if (StringUtils.isNotBlank(item.getSpguid())) {
                    info = whinfoService.getWhinfo(outform.getOrgguid(), item.getProductguid(), item.getSrguid(),
                            item.getShrguid(), item.getSpguid());
                } else {
                    //回滚
//                		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nospguid";
                    throw new CustomException("明细规格有误！");
                }
//				}
            }
            if (info != null) {
                BigDecimal lef = info.getStoreqty().subtract(item.getWeight());
                if (lef.compareTo(BigDecimal.ZERO) > -1) {
                    info.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                    whinfoService.updateWhinfo(info);
                } else {
                    //回滚
//            		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nowhinfo";
                    throw new CustomException("库存不足！");
                }
            } else {
                //回滚
//        		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                return "nowhinfo";
                throw new CustomException("库存不足！");
            }
        }
        // 更新入库单总重量
        Whoutform out = new Whoutform();
        if (outform.getOuttype() == 7) {
            out.setOuttype(6);
        }
        out.setAutoid(outform.getAutoid());
        out.setWeight(weight);
        whoutformMapper.updateWhoutform(out);
        return guid;
    }

    public String saveWhoutformNew(List<Whoutformitem> items, Whoutform outform) {
        // 生成编码
        String guid = IdUtils.fastSimpleUUID();
        outform.setGuid(guid);
        outform.setWhoutcode(codeService.getCode("7"));
        outform.setOuttime(new Date());
        outform.setCreatetime(DateUtils.getNowDate());
        whoutformMapper.insertWhoutform(outform);
        // 保存明细
        BigDecimal weight = new BigDecimal(0);
        for (Whoutformitem item : items) {
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setSrguid(outform.getSrguid());
            item.setWhoutid(guid);
            item.setOrgguid(outform.getOrgguid());
            item.setOrgname(outform.getOrgname());

            /*Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
            if (house.getShrtype() == 1) {//如果是原料库 则统一设置 原料规格出库
                Salesspecification spe = new Salesspecification();
                spe.setProductguid(item.getProductguid());
                spe.setBaseFlag(1);
                spe = salesSpecificationService.selectSalesspecificationList(spe).get(0);
                item.setSpguid(spe.getGuid());
                item.setSpename(spe.getName());
            }*/

            item.setItemguid(item.getScrapitemid());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whoutformitemMapper.insertWhoutformitem(item);
            weight = weight.add(item.getWeight());

            // 更新库存
            Whinfo info;
            if (outform.getOuttype() == 7) {// 农户库存调整查询
                info = whinfoService.getFarmerWhinfo(item.getProductguid(), item.getSrguid(), item.getShrguid());
            } else {
//				if (house.getShrtype() == 1) {// 1-原材料库，2-产成品库 3-废品库（不合格品库）
//					info = infoService.getWhinfo(outform.getOrgguid(), item.getProductguid(), item.getSrguid(),
//							item.getShrguid());
//				} else {// 产品
                if (StringUtils.isNotBlank(item.getSpguid())) {
                    info = whinfoService.getWhinfo(outform.getOrgguid(), item.getProductguid(), item.getSrguid(),
                            item.getShrguid(), item.getSpguid());
                } else {
                    //回滚
//                		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nospguid";
                    throw new CustomException("明细规格有误！");
                }
//				}
            }
            if (info != null) {
                BigDecimal lef = info.getStoreqty().subtract(item.getWeight());
                if (lef.compareTo(BigDecimal.ZERO) > -1) {
                    info.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                    whinfoService.updateWhinfo(info);
                } else {
                    //回滚
//            		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return "nowhinfo";
                    throw new CustomException("库存不足！");
                }
            } else {
                //回滚
//        		TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                return "nowhinfo";
                throw new CustomException("库存不足！");
            }
        }
        // 更新入库单总重量
        Whoutform out = new Whoutform();
        if (outform.getOuttype() == 7) {
            out.setOuttype(6);
        }
        out.setAutoid(outform.getAutoid());
        out.setWeight(weight);
        whoutformMapper.updateWhoutform(out);
        return guid;
    }

    /**
     * @return toKg: 公斤 toT ：吨
     * @Author shaodong
     * @Description 计算重量
     * @Date 17:15 2021/1/6
     * @Param spguid 规格GUID
     * @Param count  数量 or 总重量
     * @Param unitType  重量类型：1-按数量 2-按重量
     * @Param bussnessType  重量类型：1-调拨 2-销售
     **/
    public HashMap<String, BigDecimal> calculateWeight(String spguid, BigDecimal count, Integer unitType, Integer bussnessType) {
        HashMap<String, BigDecimal> result = new HashMap<>();
        if (null == count) {
            result.put(KG, BigDecimal.ZERO);
            result.put(T, BigDecimal.ZERO);
            return result;
        }
        BigDecimal toKgWeight = null;
        BigDecimal toTWeight = null;
        Salesspecification spec = salesSpecificationService.selectSalesspecificationById(spguid);

        Stockunit skunit = stockunitService.selectStockunitById(spec.getStockunitid());
        Stockunit skunitSF = stockunitService.selectStockunitById(spec.getSfunitid());

        BigDecimal toKg = skunit.getToKg();
        BigDecimal toT = skunit.getToT();
        BigDecimal netWeight = spec.getNetweight() == null ? BigDecimal.ZERO : spec.getNetweight();
        if (2 == bussnessType) {//销售
            if (2 == unitType) {//按重量下单
                if (1 == skunit.getIsUnit()) {//库存单位：重量
                    toKgWeight = count;
                    result.put(KG, toKgWeight);//明细重量
                    toTWeight = count.multiply(toT);
                    result.put(T, toTWeight);//订单重量
                } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                    System.out.println("3 - 按重量下单，库存单位为数量，不考虑此情况！");
                }
            } else if (1 == unitType) {//按数量下单
                if (1 == skunit.getIsUnit()) {//库存单位：重量
                    //20230828：销售单位sfunit是按重量，但是销售订单是案件数，这是电商订单批量生成的，把netweight设置为1
                    /*if (1 == skunitSF.getIsUnit() && BigDecimal.ZERO.compareTo(netWeight) >= 0){
                        netWeight =BigDecimal.ONE;
                    }*/
                    toKgWeight = netWeight.multiply(toKg).multiply(count);
                    if (BigDecimal.ZERO.compareTo(netWeight) >= 0 || BigDecimal.ZERO.compareTo(toKg) >= 0){
                        throw new CustomException("库存单位有误！");
                    }
                    result.put(KG, toKgWeight);//明细重量
                    toTWeight = toKgWeight.multiply(toT);/*neweight = 1*/
                    result.put(T, toTWeight);//订单重量
                } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                    toKgWeight = count;
                    result.put(KG, toKgWeight);
                    toTWeight = netWeight.multiply(toKg).multiply(toT).multiply(count);
                    result.put(T, toTWeight);
                }
            }

        } else if (3 == bussnessType) {//领料，调整,调拨
            if (1 == skunit.getIsUnit()) {//库存单位：重量
                toKgWeight = count;
                result.put(KG, toKgWeight);//明细重量
                toTWeight = count.multiply(toT);
                result.put(T, toTWeight);//订单重量
            } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                toKgWeight = count;
                result.put(KG, toKgWeight);
                toTWeight = netWeight.multiply(toKg).multiply(toT).multiply(count);
                result.put(T, toTWeight);
            }
        }
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void whinoutBack(SysUser user, String guid, Integer businessType,List<Whoutform> whoutformList){
        // 查询出库单
        Whoutform out = new Whoutform();
        out.setOrderguid(guid);
        List<Whoutform> outforms = whoutformMapper.selectBaseWhoutformList(out);
        //20230918 zhangfu 只处理最后一条出库单，以避免一张订单多次反出库之后导致问题
        Whoutform whoutform =  outforms.size()>0?outforms.get(0):null;
        if(whoutform==null){
            throw new CustomException("没有找到原始出库信息");
        }

        log.info("whoutform:"+whoutform.getGuid()+":"+whoutform.getBusinesscode());
//        for (Whoutform outform : outforms) {
//            if (outform.getWeight().compareTo(BigDecimal.ZERO) > 0) {
        if (businessType == 2){
            //处理销售单明细中的出库数量
            Sellitem si = new Sellitem();
            si.setSellguid(guid);
            List<Sellitem> sis = sellitemMapper.selectSellitemList(si);
            for (Sellitem s : sis) {
                s.setLoadweight(BigDecimal.ZERO);
                s.setUpdateBy(user.getUserId());
                s.setUpdateTime(DateUtils.getNowDate());
                sellitemMapper.updateSellitem(s);
            }
        }
        // 查询出库单明细
        Whoutformitem item = new Whoutformitem();
        item.setWhoutid(whoutform.getGuid());
        List<Whoutformitem> items = whoutformitemMapper.selectWhoutformitemList(item);

        whoutform.setItems(items);
        // 反向生成出库单
        String outformGuid = IdUtils.fastSimpleUUID();
        whoutform.setGuid(outformGuid);
        whoutform.setWhoutcode(codeService.getCode("7"));
        whoutform.setOperatorid(user.getGuid());
        whoutform.setRemark("反向生成出库单！");
//                outform.setWeight(outform.getWeight().negate());
//                outform.setLoadcount(outform.getLoadcount() != null && outform.getLoadcount() != 0 ? new BigDecimal(outform.getLoadcount()).negate().intValue() : 0);

        if (2 == businessType) {
            Sellform sellform = sellformMapper.selectSellformByGuid(guid);
            if (null == sellform.getPlantformLoadDate()) {
                whoutform.setCreatetime(DateUtils.getNowDate());
            } else {
                String overDate = sysConfigService.selectConfigByKey("over_date");
                Date outTime = MeituanDataProcessUtil.getLoadingTime(sellform.getPlantformLoadDate(), null, 2, Integer.parseInt(overDate));
                whoutform.setCreatetime(outTime);

            }
        }else{
            whoutform.setCreatetime(DateUtils.getNowDate());
        }
        whoutformMapper.insertWhoutform(whoutform);

        for (Whoutformitem it : items) {
            it.setGuid(IdUtils.fastSimpleUUID());
            it.setWhoutid(outformGuid);
            it.setLoadcount(it.getLoadcount() != null && it.getLoadcount() != 0 ? new BigDecimal(it.getLoadcount()).negate().intValue() : 0);
            it.setWeight(it.getWeight().negate());
            it.setHandsel(it.getHandsel() != null ? it.getHandsel().negate() : BigDecimal.ZERO);
            it.setHandselweight(it.getHandselweight() != null ? it.getHandselweight().negate() : BigDecimal.ZERO);
            it.setHandselcount(it.getHandselcount() != null && it.getHandselcount() != 0 ? new BigDecimal(it.getHandselcount()).negate().intValue() : 0);
            it.setCreateTime(DateUtils.getNowDate());
            it.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whoutformitemMapper.insertWhoutformitem(it);


//                    Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(it.getShrguid());

            // 更新库存信息
            Whinfo info = new Whinfo();
            //原材料库和其他类型的逻辑一样 20230918
//                    if (house.getShrtype() == 1) {// 1-原材料库，2-产成品库 3-废品库（不合格品库）
//                        info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(), it.getShrguid(), null);
//                    } else {
                info = whinfoService.getWhinfo(it.getOrgguid(), it.getProductguid(), it.getSrguid(), it.getShrguid(),
                        it.getSpguid());
//                    }
            if (info != null) {
                Whinfo upinfo = new Whinfo();
                upinfo.setGuid(info.getGuid());
                //it.weight在上面已经被处理为负数了，需要重新计算为正数
                upinfo.setStoreqty(info.getStoreqty().add(it.getWeight().negate()));
                whinfoService.updateWhinfo(upinfo);
            }

            //20231130电商，美团反出库时间;修改历史库存和动态库存
            if (2 == businessType) {
                Sellform sellform = sellformMapper.selectSellformByGuid(guid);
                if (null != sellform.getPlantformLoadDate()){
                    syncWhinfoRecords(it, sellform.getPlantformLoadDate());
                }
            }
        }
        whoutformList.add(whoutform);
            /*} else {
                break;
            }*/
//        }

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void whoutBack(String orderguid,Date backDatedDate,List<Whoutform> whoutformList){
        // 查询出库单
        Whoutform out = new Whoutform();
        out.setOrderguid(orderguid);
        List<Whoutform> outforms = whoutformMapper.selectBaseWhoutformList(out);
        //20230918 zhangfu 只处理最后一条出库单，以避免一张订单多次反出库之后导致问题
        Whoutform whoutform =  outforms.size()>0?outforms.get(0):null;
        if(whoutform==null){
            throw new CustomException("没有找到原始出库信息");
        }
        log.info("whoutform:"+whoutform.getGuid()+":"+whoutform.getBusinesscode());
        // 查询出库单明细
        Whoutformitem item = new Whoutformitem();
        item.setWhoutid(whoutform.getGuid());
        List<Whoutformitem> items = whoutformitemMapper.selectWhoutformitemList(item);

        whoutform.setItems(items);
        // 反向生成出库单
        whoutform.setOperatorid(SecurityUtils.getLoginUser().getUser().getTuserId());
        whoutform.setRemark("反向生成出库单！");

        for (Whoutformitem it : items) {
            it.setLoadcount(it.getLoadcount() != null && it.getLoadcount() != 0 ? new BigDecimal(it.getLoadcount()).negate().intValue() : 0);
            it.setWeight(it.getWeight().negate());
            it.setHandsel(it.getHandsel() != null ? it.getHandsel().negate() : BigDecimal.ZERO);
            it.setHandselweight(it.getHandselweight() != null ? it.getHandselweight().negate() : BigDecimal.ZERO);
            it.setHandselcount(it.getHandselcount() != null && it.getHandselcount() != 0 ? new BigDecimal(it.getHandselcount()).negate().intValue() : 0);
        }
        whoutform.setWeight(BigDecimal.ZERO);
        this.whout(whoutform, items, false, backDatedDate);

        whoutformList.add(whoutform);

    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void generateNewWhoutform(ArrayList<Whoutform> whoutforms,Sellform sellform){
        //目前暂时不存在一条业务数据在一次出库的时候产生多条出库单的情况，所以只处理第一条
        Whoutform wof=whoutforms.get(0);
        List<Whoutformitem> whoutformitems = wof.getItems();
        List<Sellitem> sellitems = sellform.getItems();

        //首先生成入库单主表
        String outformGuid = IdUtils.fastSimpleUUID();
        wof.setGuid(outformGuid);
        wof.setAutoid(null);
        wof.setWhoutcode(codeService.getCode("7"));
        wof.setRemark("系统自动重新生成出库单！");
        wof.setCreatetime(DateUtils.getNowDate());
        whoutformMapper.insertWhoutform(wof);

        for(Whoutformitem item:whoutformitems){
            for (int i = 0; i < sellitems.size(); i++) {
                Sellitem sellitem = sellitems.get(i);
                if (item.getItemguid().equals(sellitem.getGuid())){
                    item.setPrice(sellitem.getPrice());
                    break;
                }
            }
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setWeight(item.getWeight().negate());
            item.setWhoutid(outformGuid);
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whoutformitemMapper.insertWhoutformitem(item);

            //更新库存
            Whinfo info = whinfoService.getWhinfo(item.getOrgguid(), item.getProductguid(), item.getSrguid(), item.getShrguid(),
                    item.getSpguid());
            if (info != null) {
                Whinfo upinfo = new Whinfo();
                upinfo.setGuid(info.getGuid());
                upinfo.setStoreqty(info.getStoreqty().add(item.getWeight()));
                whinfoService.updateWhinfo(upinfo);
            }
        }



    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public AjaxResult saveWhoutFormAndImg(Long id, Whoutform entity, String fileIds, String opinion, Long taskid, String opttype) {
        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        List<Whoutformitem> items = entity.getItems();
        entity.setIsCopytoKD(1);
        String guid = "";
        String orderid = "";
        BigDecimal weight = new BigDecimal(0);// 净重
        int type = Integer.parseInt(opttype);
        Long stockunitid = null;
        String stockunit = null;
        //1弃用
        /*if (1 == type) {
            // 查询采购单
            Purchaseform pf = new Purchaseform();
            pf.setGuid(orderid);
            pf = pfService.view("findDetail", pf);
            // 出库单数据组装
            guid = setPfWhoutform(entity, orderid, user, type, pf);
            // 保存 明细
            for (Whoutformitem item : items) {
                item.setWhoutid(guid);
                item.setSrguid(pf.getStorermguid());
                item.setOrgguid(pf.getSorgguid());
                item.setOrgname(pf.getSorgname());
                weight = weight.add(item.getWeight());
//				lbweight = weight;
                itemDao.insert(item);

                // 更新库存信息
                Whinfo info = infoService.getWhinfo(pf.getSorgguid(), item.getProductguid(), item.getSrguid(),
                        item.getShrguid());
                if (info != null) {
                    BigDecimal lef = info.getStoreqty().subtract(item.getWeight());
                    if (lef.compareTo(BigDecimal.ZERO) > -1) {
                        info.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                        infoService.update(info);
                    } else {
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        result = "noWhinfo";// 没有库存信息
                        return result;
                    }
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    result = "noWhinfo";// 没有库存信息
                    return result;
                }
                // 更新采购明细发货重量
                pitemService.updatePI(orderid, item.getProductguid(), item.getSpguid(), item.getWeight());
            }
            /// 更新采购单状态
            updatePF(orderid);
            saleformService.createSF(orderid);
        } else*/
        if (2 == type) { //2销售出库
            //获取销售订单
            Sellform sf = new Sellform();
            sf.setId(id);
            sf = sellformMapper.findDetail(sf);
            orderid = sf.getGuid();
            //校验，计算重量
            int loadcount = 0;
            for (Whoutformitem item : items) {
                HashMap<String, BigDecimal> weightHash = null;
                int settletype = sf.getSettletype();
                if (1 == settletype) {
                    item.setLoadcount(item.getWeight().intValue());
                    loadcount = loadcount + item.getLoadcount();
                    weightHash = calculateWeight(item.getSpguid(), new BigDecimal(item.getLoadcount()), settletype
                            , 2);
                    item.setWeight(weightHash.get(KG));
                    calculateHandsel(item, item.getLoadcount());
                    HashMap<String, BigDecimal> handleWeightHash = calculateWeight(item.getSpguid()
                            , item.getHandsel() == null ? BigDecimal.ZERO : item.getHandsel(), settletype, 2);
                    item.setHandselweight(handleWeightHash.get(KG));
                    weight = weight.add(weightHash.get(T));
                }
                if (2 == settletype) {
                    BigDecimal weightsf = calculateWeightSF(item.getSpguid() == null ? item.getRawspguid() : item.getSpguid(), item.getSfunitid(),
                            item.getWeight(), true);
                    item.setWeight(weightsf);
                    weight = weight.add(item.getWeight());

                }
                //这里是原来没有itemguid才这么做的，现在有了，前端赋值直接给itemguid赋值
//                item.setItemguid(item.getOrderItemGuid());
                //已使用销售明细计算过出库明细重量，现将出库明细单位写入
                Salesspecification spec = salesSpecificationService.selectSalesspecificationById(item.getSpguid());
                stockunitid = spec.getStockunitid();
                stockunit = spec.getStockunit();
                item.setStockunitid(stockunitid);
                item.setStockunit(stockunit);
                item.setSrguid(sf.getStorermguid());
                item.setProductguid(spec.getProductguid());
            }
            entity.setLbweight(weight);
            //出库数据准备
            setDataPrepared(entity, sf, orderid, opttype, sysUser);
            //跨库房出库拆分出库单
            List<List<Whoutformitem>> eList = getChildItems(entity, items);
            //出库
            for (List<Whoutformitem> outItem : eList) {
                if (outItem.size() > 0) {
                    /*HashMap<String, Object> res = */orgOut(entity, outItem, sf);
//                    if (!"success".equalsIgnoreCase((String) res.get("msg"))) {
//                        return AjaxResult.error("库存不足");
//                    }
                }
            }

            //更新销售明细出库重量与数量
            List<Sellspitem> spitems = updateSellitems(orderid, items, sysUser, sf.getSettletype());

            //202306123预收款判断处理
            if (sf.getPaytype()== 1 &&(sf.getPartitionflag() == 3 || sf.getPartitionflag() == 4)){
                Sellform sellform = new Sellform();
                sellform.setId(id);
                sellform = sellformMapper.findDetail(sellform);
                childWhoutSettleFinalAmount(sellform,true);
            }

            //2023.09.13 18:15:12 货到付款结算确认后的反出库处理：结算确认后，如果单价发生了变化（只要price!=settleprice就算是结算单价发生了变化），
            // 需要原出库单反出库、按照新的单价重新出库。
            if (taskid == null){
                return null;
            }
            //更新销售单状态
            String result = updateSellform(entity, orderid, sysUser, taskid, weight, loadcount, sf, spitems, fileIds, opinion);
            if (!result.equals("success")) {
                return AjaxResult.error(result);
            }

            /* *
             * 2020-07-21 出库后 更新物流单 装车状态
             **/

            Wlinfoitem wlitem = wlinfoitemMapper.selectWlinfoitemByOrderId(orderid);
            if (wlitem != null) {
                // 单一订单
                if (wlitem.getWlstatus().equals("0")) {
                    handleWlinfo(wlitem, sysUser);
                } else {
                    // 非单一订单的时候 查询其他订单是否已出库 ，若已出库 则更新物流单装车状态
                    Wlinfoitem item = new Wlinfoitem();
                    item.setWlinfoid(wlitem.getWlinfoid());
                    List<Wlinfoitem> wlitems = wlinfoitemMapper.selectWlinfoitemList(item);

                    String[] orderids = new String[wlitems.size()];
                    for (int i = 0; i < wlitems.size(); i++) {
                    }

                    List<String> arrList = new ArrayList<>(Arrays.asList(orderids));
                    arrList.remove(arrList.indexOf(orderid));
                    String[] orderidss = arrList.toArray(new String[arrList.size()]);

                    Sellform sel = new Sellform();
                    sel.setIds(orderidss);
                    sel.setLtstatus(45);// 未出库
                    List<Sellform> sflist = sellformMapper.selectSellformList(sel);
                    if (sflist.size() < 1) {// 都已出库
                        handleWlinfo(wlitem, sysUser);
                    }
                }
            }

            Sellform sellform = new Sellform();
            sellform.setId(id);
            sellform = sellformMapper.findDetail(sellform);

            sellformService.settleOne(null, sysUser, sellform);
//            if (sellform.getPaytype() == 1){//全额预付，就在出库节点做核销处理，否则就在结算确认节点做
            //2023-10-16 按件数的，需要在出库的时候生成核销队列
            //2023-10-18 上车付款的，出库节点不再生成核销队列，充值完成后的回调节点处理
//            if (StringUtils.equalsIgnoreCase("36", sellform.getFlowtempguid()) &&
            if (sellformService.availableRecbalance(sellform,1)
                    && (sellform.getSettletype() == 1)
                    && sellform.getPaytype() != 2){
                sellformService.settleHexiao(sellform, sysUser);
            }
            //20231010 销售订单出库，代码逻辑混乱。。。本来应该在出库流程操作前完成，但是现在只能暂时放在流程后
            //20231010 形成针对非全额预付的、非样品订单，生成应收账款记录

            sellformService.generateRecievableBalance(sellform,1);


        } else if (4 == type) {// 领料出库
            BigDecimal pricesum = new BigDecimal(0);
            // 查询领料单
            Pickinglist sf = pickinglistMapper.findDetail(id);
            orderid = sf.getGuid();
            //创建出库单
            entity.setDepartmentid(sf.getDepartmentid());
            try {
                guid = createPlWhoutform(entity, orderid, sysUser, opttype, sf);
            } catch (Exception e) {
                e.printStackTrace();
                return AjaxResult.error();
            }
            //创建出库单明细
            for (Whoutformitem item : items) {
                item.setWhoutid(guid);
                item.setSrguid(sf.getStrmid());
                item.setOrgguid(sf.getOrgid());
                item.setOrgname(sf.getOrgname());

                Storehouseroom house = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
                if (house.getShrtype() == 1) {
                    Salesspecification spec = salesSpecificationService.getBaseMatril(item.getProductguid());
                    stockunitid = spec.getStockunitid();
                    stockunit = spec.getStockunit();
                    item.setSpguid(spec.getGuid());
                }
                if (house.getShrtype() != 4) { //辅料不参与计算
                    try {
                        weight = weight.add(this.calculateWeight(item.getSpguid(), item.getWeight(), null, 3).get("toT"));
                    } catch (Exception e) {
                        e.printStackTrace();
                        return AjaxResult.error();
                    }
                }

                item.setGuid(IdUtils.fastSimpleUUID());
                item.setCreateTime(DateUtils.getNowDate());
                item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
                whoutformitemMapper.insertWhoutformitem(item);

                //更新库存
                Whinfo info = whinfoService.getWhinfo(sf.getOrgid(), item.getProductguid(), item.getSrguid(),
                        item.getShrguid(), item.getSpguid());
                if (info != null) {
                    BigDecimal lef = info.getStoreqty().subtract(item.getWeight());
                    if (lef.compareTo(BigDecimal.ZERO) > -1) {
                        info.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                        whinfoService.updateWhinfo(info);
                    } else {
//                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                        return AjaxResult.error("没有库存信息");
                        throw new CustomException("没有库存信息！");
                    }
                } else {
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    return AjaxResult.error("没有库存信息");
                    throw new CustomException("没有库存信息！");
                }
                // 更新领料单明细
                BigDecimal priceitem = pickinglistitemService.updatePI(orderid, item.getProductguid(), item.getShrguid(),
                        item.getWeight(), info.getPrice(), item.getSpguid());
                pricesum = pricesum.add(priceitem);

                //更新领料单明细出库重量
                Pickinglistitem it = new Pickinglistitem();
                it.setGuid(item.getItemguid());
                it.setOutweight(item.getWeight());
                pickinglistitemMapper.updatePickinglistitem(it);
            }

            sf.setPlatformId(sf.getStrm());
            FlowResult result = processUtils.defaultApproval(taskid, fileIds, opinion, sf
                    , sysUser);
            if (result.getMsg().equals(ResultParam.SUCCESS)) {
                Pickinglist sfo = new Pickinglist();
                sfo.setGuid(orderid);
                sfo.setLastupdate(new Date());
                sfo.setWeightsum(weight);
                sfo.setPricesum(pricesum);
                sfo.setStatus(result.getNextStat());
                pickinglistMapper.updatePickinglist(sfo);
            } else {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.error(result.getMsg());
            }

        }
        // 更新总重量
        Whoutform wf = new Whoutform();
        wf.setGuid(guid);
        wf.setWeight(weight);
        whoutformMapper.updateWhoutformGuid(wf);
        // 保存过磅单信息
        Weighlist weightlist = new Weighlist();
        weightlist.setFoguid(orderid);
        weightlist.setWtype(type);
        weightlist.setWeight(entity.getLbweight());
        weightlist.setOperator(sysUser.getTuserId());
        weightlist.setStockunitid(stockunitid);
        weightlist.setStockunit(stockunit);
        weightlist.setGuid(IdUtils.fastSimpleUUID());
        weighlistMapper.insertWeighlist(weightlist);


        return AjaxResult.success();
    }

    @Override
    public AjaxResult printWhout(Long autoid) {
        Map<String, Object> map = getwhoutPrintData(autoid);

        return excelTempUtil.exportWhout(map);
    }

    @Override
    public AjaxResult printWhoutHtml(Long autoid) {
        Map<String, Object> map = getwhoutPrintData(autoid);

        return excelTempUtil.exportWhoutHtml(map);
    }

    private Map<String, Object> getwhoutPrintData(Long autoid) {
        Whoutform whoutform = whoutformMapper.findWhoutPrint(autoid);
        String supplier = null;
        String customer = null;
        String submitter = null;
        Date orderDate = null;
        String deptName = null;
        if (2 == whoutform.getOuttype()){
            Sellform sellform = sellformMapper.selectSellformByGuid(whoutform.getOrderguid());
//            supplier = sellform.getOrgName();
            customer = sellform.getCustomername();
            submitter = sellform.getApplyname();
            orderDate = sellform.getCreatetime();
            deptName = sellform.getDepname();
        }
        if (3 == whoutform.getOuttype() || 6 == whoutform.getOuttype()){
            Transferapply transferapply = transferapplyService.selectTransferapplyById(whoutform.getOrderguid());
//            supplier = transferapply.getOrgname();
//            customer = transferapply.getToorgname();
            submitter = transferapply.getApplyname();
            orderDate = transferapply.getCreatetime();
            deptName = transferapply.getDepartname();
        }
        if (4 == whoutform.getOuttype()){
            Pickinglist pickinglist = pickinglistMapper.selectPickinglistById(whoutform.getOrderguid());
//            supplier = pickinglist.getOrgname();
//            customer = pickinglist.getToorgname();
            submitter = pickinglist.getCreateName();
            orderDate = pickinglist.getCreatetime();
            deptName = pickinglist.getDeptName();
        }
        if (5 == whoutform.getOuttype()){
            Scrapapply scrapapply = scrapapplyMapper.getDetail(whoutform.getOrderguid());
//            supplier = transferapply.getOrgname();
//            customer = transferapply.getToorgname();
            submitter = scrapapply.getOperator();
            orderDate = scrapapply.getCreatetime();
            deptName = scrapapply.getDeptName();
        }
        if (7 == whoutform.getOuttype()){
            Freightorder freightorder = freightorderMapper.selectFreightorderById(whoutform.getOrderguid());
//            supplier = freightorder.getOrgname();
            customer = freightorder.getPlantor();
            submitter = freightorder.getOperator();
            orderDate = freightorder.getCreatetime();
            deptName = freightorder.getDepartment();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("orgName", whoutform.getOrgFullName());
        map.put("typeName", whoutform.getOuttypename());
        map.put("code", whoutform.getBusinesscode());//订单编号
        map.put("customerName", customer);//客户
        map.put("whname", whoutform.getStoreroom());//库房
        map.put("submitter", submitter);//提交人
        map.put("orderDate", orderDate);//订单日期
        map.put("whoutDate", whoutform.getOuttime());//出入库日期
        map.put("whOperator", whoutform.getOperator());//库管
        map.put("deptName", deptName);//库管

        map.put("list", whoutform.getItems());
        return map;
    }
    //子订单出库时，计算当前订单的结算金额2=订单单价*订单数量，结算金额1=订单单价*出库数量，
    // 更新主订单finalamount=finalamount+结算金额2-结算金额1；子订单反出库时做相反操作

    /**
     *
     * @param sf：子订单
     * @param reverse true:出库 false:反出库
     */
    public void childWhoutSettleFinalAmount(Sellform sf, Boolean reverse) {
        Sellform sellformParent = sellformMapper.selectSellformByGuid(sf.getParentguid());
        if (null != sellformParent.getFinalamount()) {
            List<Sellitem> pitems = sf.getItems();
            List<Sellspitem> spitems = sf.getSpitems();
            //结算金额2=订单单价*订单数量
            BigDecimal curr_Order_Amt = new BigDecimal(0);
            //结算金额2=订单单价*订单数量
            BigDecimal curr_Order_Amt_Out = new BigDecimal(0);
            for (Sellitem b : pitems) {
                if (StringUtils.isBlank(b.getSuitpackid())) {
                    curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply((b.getWeight())));
                    curr_Order_Amt_Out = curr_Order_Amt_Out.add(b.getPrice().multiply((b.getLoadweight())));
                }
            }
            if (spitems.size() > 0) {
                for (Sellspitem b : spitems) {
                    curr_Order_Amt = curr_Order_Amt.add(b.getPrice().multiply(new BigDecimal(b.getOrderpack())));
                    curr_Order_Amt_Out = curr_Order_Amt_Out.add(b.getPrice().multiply(new BigDecimal(b.getLoadcount())));
                }
            }
            Sellform sellform = new Sellform();
            sellform.setGuid(sf.getParentguid());
            if (reverse) {
                sellform.setFinalamount(sellformParent.getFinalamount().add(curr_Order_Amt).subtract(curr_Order_Amt_Out));
            } else {
                sellform.setFinalamount(sellformParent.getFinalamount().add(curr_Order_Amt_Out).subtract(curr_Order_Amt));
            }
            sellformMapper.updateSellform(sellform);
        }
    }

    private String createPlWhoutform(Whoutform entity, String orderid, SysUser user, String opttype, Pickinglist sf) throws Exception {
        Produceplan plan = produceplanMapper.selectProduceplanById(sf.getProduceplanid());
        // 出库单数据组装
        entity.setBusinesscode(sf.getCode());
        entity.setOrderguid(orderid);
        entity.setOrgguid(sf.getOrgid());
        entity.setOrgname(sf.getOrgname());
        // 生成编码
        String code = codeService.getCode("7");
        entity.setWhoutcode(code);
        entity.setOuttype(Integer.parseInt(opttype));
        entity.setSrguid(sf.getStrmid());
        entity.setOperatorid(user.getGuid());
        entity.setOuttime(DateUtils.getNowDate());
        entity.setCreatetime(DateUtils.getNowDate());
        String guid = IdUtils.fastSimpleUUID();
        entity.setGuid(guid);
        entity.setCreatetime(DateUtils.getNowDate());
        whoutformMapper.insertWhoutform(entity);
        return guid;
    }

    /**
     * @return toKg: 公斤 toT ：吨
     * @Author shaodong
     * @Description 计算重量
     * @Date 17:15 2021/1/6
     * @Param spguid 规格GUID
     * @Param count  数量 or 总重量
     * @Param unitType  重量类型：1-按数量 2-按重量
     * @Param bussnessType  重量类型：1-调拨 2-销售
     **/
    public HashMap<String, BigDecimal> calculateWeightForSaveSF(String spguid, BigDecimal count, Integer unitType
            , Integer bussnessType) {
        HashMap<String, BigDecimal> result = new HashMap<>();
        if (null == count) {
            result.put(KG, BigDecimal.ZERO);
            result.put(T, BigDecimal.ZERO);
            return result;
        }
        BigDecimal toKgWeight = null;
        BigDecimal toTWeight = null;
        Salesspecification spec = salesSpecificationService.selectSalesspecificationById(spguid);

        Stockunit skunit = stockunitService.selectStockunitById(spec.getSfunitid());

        BigDecimal toKg = skunit.getToKg();
        BigDecimal toT = skunit.getToT();
        BigDecimal netWeight = spec.getNetweight() == null ? BigDecimal.ZERO : spec.getNetweight();
        ;
        if (2 == bussnessType) {//销售
            if (2 == unitType) {//按重量下单
                if (1 == skunit.getIsUnit()) {//库存单位：重量
                    toKgWeight = count;
                    result.put(KG, toKgWeight);//明细重量
                    toTWeight = count.multiply(toT);
                    result.put(T, toTWeight);//订单重量
                } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                    System.out.println("3 - 按重量下单，库存单位为数量，不考虑此情况！");
                }
            } else if (1 == unitType) {//按数量下单
                if (1 == skunit.getIsUnit()) {//库存单位：重量
                    toKgWeight = netWeight.multiply(toKg).multiply(count);
                    result.put(KG, toKgWeight);//明细重量
                    toTWeight = toKgWeight.multiply(toT);/*neweight = 1*/
                    result.put(T, toTWeight);//订单重量
                } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                    toKgWeight = count;
                    result.put(KG, toKgWeight);
                    toTWeight = netWeight.multiply(toKg).multiply(toT).multiply(count);
                    result.put(T, toTWeight);
                }
            }

        } else if (3 == bussnessType) {//领料，调整,调拨
            if (1 == skunit.getIsUnit()) {//库存单位：重量
                toKgWeight = count;
                result.put(KG, toKgWeight);//明细重量
                toTWeight = count.multiply(toT);
                result.put(T, toTWeight);//订单重量
            } else if (0 == skunit.getIsUnit()) {//库存单位：数量
                toKgWeight = count;
                result.put(KG, toKgWeight);
                toTWeight = netWeight.multiply(toKg).multiply(toT).multiply(count);
                result.put(T, toTWeight);
            }
        }
        return result;
    }

    /**
     * @return
     * @Author shaodong
     * @Description //销售出库按照订单赠送数量所占订单总数量的比重来计算实际赠送数量
     * @Date 14:58 2021/1/28
     * @Param
     **/
    private void calculateHandsel(Whoutformitem item, int loadCount) {
        Sellitem si = sellitemMapper.selectSellitemById(item.getItemguid());
        BigDecimal orderCount = si.getWeight();
        BigDecimal handselcount = new BigDecimal(si.getHandselcount() == null ? 0 : si.getHandselcount());
        if (null != handselcount) {
            BigDecimal handSel = (handselcount.multiply(new BigDecimal(loadCount)).divide(orderCount.add(handselcount), 4,  BigDecimal.ROUND_HALF_DOWN)).setScale(0, BigDecimal.ROUND_HALF_EVEN);
            item.setHandsel(handSel);
        }
    }

    /**
     * @return
     * @Author shaodong
     * @Description //BUG:794
     * @Date 15:17 2021/2/4
     * @Param zf:true正算，通过销售明细算出库明细重量，false:通过出库明细算销售明细重量
     **/
    public BigDecimal calculateWeightSF(String spguid, Long stockunitid, BigDecimal count, boolean zf) {
        if (null == count) {
            return BigDecimal.ZERO;
        }
        Salesspecification spec = salesSpecificationService.selectSalesspecificationById(spguid);

        Stockunit spunit = stockunitService.selectStockunitById(spec.getStockunitid());

        Stockunit sellItemunit = stockunitService.selectStockunitById(stockunitid);

        BigDecimal tospT = spunit.getToT();
        BigDecimal tosfT = sellItemunit.getToT();
        if (zf) {
            return count.multiply(tosfT).divide(tospT);
        } else {
            return count.divide(tosfT).multiply(tospT);
        }
    }

    /**
     * @return
     * @Author shaodong
     * @Description销售出库添加字段
     * @Date 14:05 2020/12/25
     * @Param 数据准备
     **/
    private void setDataPrepared(Whoutform entity, Sellform sf, String orderid, String opttype, SysUser user) {
        entity.setDepartmentid(sf.getDepguid());
        entity.setOuttype(Integer.parseInt(opttype));
        entity.setOrderguid(orderid);
        entity.setOperatorid(user.getGuid());
        entity.setSrguid(sf.getStorermguid());
        entity.setBusinesscode(sf.getSellcode());
        entity.setSettlOrgId(sf.getSorgguid());
        entity.setSettlOrgName(sf.getSorgname());
        entity.setRevCustId(sf.getCustomerguid());
        entity.setRevCustName(sf.getName());
        entity.setCurrency(sf.getCurrency());
        entity.setOuttime(new Date());
        Storeroom room = storeroomMapper.selectStoreroomByGuid(entity.getSrguid());
        entity.setOrgguid(room.getOrgguid());
        entity.setOrgname(room.getOrgname());
    }

    /**
     * 更新每日库存数据以及动态库存--出库
     * @param item
     * @param plantformLoadDate
     */
    public void syncWhinfoRecords(Whoutformitem item, Date plantformLoadDate){
        if (DateUtils.getNowDate().getDay() != plantformLoadDate.getDay()){

            Whinforecord whinforecord = new Whinforecord();
            whinforecord.setOrgguid(item.getOrgguid());
            whinforecord.setStorermguid(item.getSrguid());
            whinforecord.setStorehguid(item.getShrguid());
            whinforecord.setProductid(item.getProductguid());
            whinforecord.setSpguid(item.getSpguid());
            whinforecord.setStarttime(DateUtils.format(plantformLoadDate));
            List<Whinforecord> whinforecords = whinforecordService.selectWhinforecordList(whinforecord);
            for (Whinforecord wfr: whinforecords){
                Whinforecord wfrUp = new Whinforecord();
                wfrUp.setId(wfr.getId());
                wfrUp.setStoreqty((wfr.getStoreqty()==null ? BigDecimal.ZERO:wfr.getStoreqty()).subtract(item.getWeight()));
                whinforecordService.updateWhinforecord(wfrUp);
            }
            //TODO 如果有rpt则更新，如果没有则插入
            RptStoreanalysis rptStoreanalysis = new RptStoreanalysis();
            rptStoreanalysis.setCompanyid(item.getOrgguid());
            rptStoreanalysis.setSrguid(item.getSrguid());
            rptStoreanalysis.setShguid(item.getShrguid());
            rptStoreanalysis.setProductid(item.getProductguid());
            rptStoreanalysis.setSpecid(item.getSpguid());
            rptStoreanalysis.setRptdate(DateUtils.format(plantformLoadDate));
            List<RptStoreanalysis> rptStoreanalysisList = rptStoreanalysisMapper.selectRptStoreanalysisList(rptStoreanalysis);
            if (rptStoreanalysisList.size() > 0){
                RptStoreanalysis rpt = rptStoreanalysisList.get(0);
                RptStoreanalysis rptStore = new RptStoreanalysis();
                rptStore.setGuid(rpt.getGuid());
                rptStore.setSelloutweight((rpt.getSelloutweight() == null ? BigDecimal.ZERO:rpt.getSelloutweight()).add(item.getWeight()));
                rptStoreanalysisMapper.updateRptStoreanalysis(rptStore);
            }else{
                Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(item.getSrguid());
                Storehouseroom storehouseroom = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
                Organization organization = organizationMapper.selectOrganizationById(item.getOrgguid());
                Productinfo productinfo = productinfoMapper.selectProductinfoById(item.getProductguid());
                Salesspecification salesspecification = salesSpecificationService.selectSalesspecificationById(item.getSpguid());
                Stockunit stockunit = stockunitService.selectStockunitById(item.getStockunitid());

                rptStoreanalysis.setSrname(storeroom.getName());
                rptStoreanalysis.setShname(storehouseroom.getName());
                rptStoreanalysis.setCompanyname(organization.getName());
                rptStoreanalysis.setProductname(productinfo.getProductname());
                rptStoreanalysis.setSpecname(salesspecification.getName());
                rptStoreanalysis.setStockunitid(item.getStockunitid());
                rptStoreanalysis.setStockunit(stockunit.getUnitName());
                rptStoreanalysis.setSelloutweight(item.getWeight());
                rptStoreanalysis.setGuid(IdUtils.fastSimpleUUID());
                rptStoreanalysisMapper.insertRptStoreanalysis(rptStoreanalysis);
            }
        }

    }

    /**
     * 更新每日库存数据以及动态库存--入库
     * @param item
     * @param plantformLoadDate
     */
    public void syncWhinfoRecords(Whinformitem item, Date plantformLoadDate, Date plantformLoadDateBase){
        Whinforecord whinforecord = new Whinforecord();
        whinforecord.setOrgguid(item.getOrgguid());
        whinforecord.setStorermguid(item.getSrguid());
        whinforecord.setStorehguid(item.getShrguid());
        whinforecord.setProductid(item.getProductguid());
        whinforecord.setSpguid(item.getSpguid());
        whinforecord.setRecorddate(DateUtils.format(plantformLoadDate));
        List<Whinforecord> whinforecords = whinforecordService.selectWhinforecordList(whinforecord);
        if (whinforecords.size() == 0){
//            whinforecord.setStorehcode();
            whinforecord.setProductname(item.getProduct());
            whinforecord.setStoreqty(item.getWeight());
            whinforecord.setStockunitid(item.getStockunitid());
            whinforecord.setStockunit(item.getStockunit());
            whinforecord.setPrice(item.getPrice());
            whinforecord.setWistartdate(DateUtils.format(plantformLoadDate));
            whinforecord.setWienddate(DateUtils.format(plantformLoadDate));
            whinforecord.setCreatedate(item.getCreatedate());
//            whinforecord.setOperatorid(SecurityUtils.getLoginUser().getUser().getTuserId());
            whinforecord.setOrgguid(item.getOrgguid());
            whinforecord.setSpguid(item.getSpguid());
            whinforecord.setGuid(IdUtils.fastSimpleUUID());
            whinforecordService.insertWhinforecord(whinforecord);
        }else{
            Whinforecord wfr = new Whinforecord();
            wfr.setId(whinforecords.get(0).getId());
            wfr.setStoreqty(whinforecords.get(0).getStoreqty().add(item.getWeight()));
            whinforecordService.updateWhinforecord(wfr);
        }

        //处理当天动态库存
        if (null != plantformLoadDateBase){
            this.updateRpt(item, DateUtils.format(plantformLoadDateBase));
        }
        //继续处理每日库存统计
        Date nextDate = DateUtils.addDay(DateUtils.format(plantformLoadDate), 1);
        if (DateUtils.getDateDiff(DateUtils.getNowDay(), nextDate) >= 0){
            this.syncWhinfoRecords(item, nextDate, null);
        }
    }
    /**
     * 更新每日库存数据以及动态库存--入库--更新、插入当天动态库存
     * @param item
     * @param plantformLoadDate
     */
    private void updateRpt(Whinformitem item, Date plantformLoadDate) {
        //TODO 如果有rpt则更新，如果没有则插入
        RptStoreanalysis rptStoreanalysis = new RptStoreanalysis();
        rptStoreanalysis.setCompanyid(item.getOrgguid());
        rptStoreanalysis.setSrguid(item.getSrguid());
        rptStoreanalysis.setShguid(item.getShrguid());
        rptStoreanalysis.setProductid(item.getProductguid());
        rptStoreanalysis.setSpecid(item.getSpguid());
        rptStoreanalysis.setRptdate(DateUtils.format(plantformLoadDate));
        List<RptStoreanalysis> rptStoreanalysisList = rptStoreanalysisMapper.selectRptStoreanalysisList(rptStoreanalysis);
        if (rptStoreanalysisList.size() > 0){
            RptStoreanalysis rpt = rptStoreanalysisList.get(0);
            RptStoreanalysis rptStore = new RptStoreanalysis();
            rptStore.setGuid(rpt.getGuid());
            rptStore.setSelloutweight(rpt.getSelloutweight().add(item.getWeight()));
            rptStoreanalysisMapper.updateRptStoreanalysis(rptStore);
        }else{
            Storeroom storeroom = storeroomMapper.selectStoreroomByGuid(item.getSrguid());
            Storehouseroom storehouseroom = storehouseroomMapper.selectStorehouseroomById(item.getShrguid());
            Organization organization = organizationMapper.selectOrganizationById(item.getOrgguid());
            Productinfo productinfo = productinfoMapper.selectProductinfoById(item.getProductguid());
            Salesspecification salesspecification = salesSpecificationService.selectSalesspecificationById(item.getSpguid());
            Stockunit stockunit = stockunitService.selectStockunitById(item.getStockunitid());

            rptStoreanalysis.setSrname(storeroom.getName());
            rptStoreanalysis.setShname(storehouseroom.getName());
            rptStoreanalysis.setCompanyname(organization.getName());
            rptStoreanalysis.setProductname(productinfo.getProductname());
            rptStoreanalysis.setSpecname(salesspecification.getName());
            rptStoreanalysis.setStockunitid(item.getStockunitid());
            rptStoreanalysis.setStockunit(stockunit.getUnitName());
            rptStoreanalysis.setSelloutweight(item.getWeight());
            rptStoreanalysis.setGuid(IdUtils.fastSimpleUUID());
            rptStoreanalysisMapper.insertRptStoreanalysis(rptStoreanalysis);
        }
    }

    /**
     * @return
     * @Author shaodong
     * @Description 销售跨库房出库，明细中库房及公司不同，由此将明细分组，分别生成出库单及对应明细，出库单重量
     * @Date 15:25 2020/12/29
     * @Param
     **/
    private List<List<Whoutformitem>> getChildItems(Whoutform entity, List<Whoutformitem> items) {
        List<List<Whoutformitem>> eList = new ArrayList<List<Whoutformitem>>();
        List<Whoutformitem> copyItems = new ArrayList<Whoutformitem>();
        copyItems.addAll(items);
        List<Whoutformitem> iList = split(eList, entity, copyItems, true);
        if (iList.size() > 0) {
            for (int i = 0; i < iList.size(); i++) {
                if (iList.size() > 0) {
                    iList = split(eList, entity, iList, false);
                    i--;
                }
            }
        }
        return eList;
    }

    /**
     * @param eList    存储明细集合的结果集
     * @param entity   出库单主表实体
     * @param sList    所有明细或者分拆出来的跨库房明细
     * @param isMainSr true:第一次分拆，去除未跨库房的明细
     * @return
     */
    public List<Whoutformitem> split(List<List<Whoutformitem>> eList, Whoutform entity, List<Whoutformitem> sList, boolean isMainSr) {
        String compareSr = null;
        compareSr = sList.get(0).getSrguid();
        List<Whoutformitem> iList = new ArrayList<>();
        for (int s = 0; s < sList.size(); s++) {
            Whoutformitem item = sList.get(s);
            if (!item.getSrguid().equalsIgnoreCase(compareSr)) {
                iList.add(item);
                sList.remove(item);
                s--;
            }
        }
        eList.add(sList);
        return iList;
    }

    /**
     * @return
     * @Author shaodong
     * @Description //出库单写入新增字段
     * @Date 11:48 2020/12/25
     * @Param
     **/
    public void orgOut(Whoutform entity, List<Whoutformitem> items, Sellform sf) {
//        HashMap<String, Object> result = new HashMap<>();
        // 生成编码
        entity.setWhoutcode(codeService.getCode("7"));
        Integer quitSRType = sf.getQuitsrtype();
        entity.setSrguid(items.get(0).getSrguid());
        Storeroom room = storeroomMapper.selectStoreroomByGuid(items.get(0).getSrguid());
        String orgguid = room.getOrgguid();
        String orgname = room.getOrgname();
        entity.setOrgguid(orgguid);
        entity.setOrgname(orgname);
        String guid = IdUtils.fastSimpleUUID();
        entity.setGuid(guid);

        if (null == sf.getPlantformLoadDate()){
            entity.setCreatetime(DateUtils.getNowDate());
        }else{
            String overDate = sysConfigService.selectConfigByKey("over_date");
            Date outTime = MeituanDataProcessUtil.getLoadingTime(sf.getPlantformLoadDate(),null,2,Integer.parseInt(overDate));
            entity.setCreatetime(outTime);

        }
        whoutformMapper.insertWhoutform(entity);

//        BigDecimal childWeight = BigDecimal.ZERO;
        for (Whoutformitem item : items) {
            Salesspecification spec = salesSpecificationService.getBaseMatril(item.getProductguid());
            if (quitSRType == 1) {
                item.setSpguid(spec.getGuid());
            }
            item.setWhoutid(guid);
            item.setOrgguid(orgguid);
            item.setOrgname(orgname);

            int settletype = sf.getSettletype();
            if (1 == settletype) {
                if (0 == item.getLoadcount()) {
                    continue;
                }
            }
            if (2 == settletype) {
                if (null == item.getWeight()) {
                    continue;
                }
            }
            item.setGuid(IdUtils.fastSimpleUUID());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(SecurityUtils.getLoginUser().getUser().getUserId());
            whoutformitemMapper.insertWhoutformitem(item);

//            childWeight = childWeight.add(item.getWeight());
            // 更新库存信息
            Whinfo info = new Whinfo();
            info = whinfoService.getWhinfo(orgguid, item.getProductguid(), item.getSrguid(), item.getShrguid(),
                    item.getSpguid());
            if (info != null) {
                //如果是采收生成的货到付款的销售订单，出库不考虑库存
                BigDecimal lef;
                if (sf.getAutoType() == 2/* && sf.getPaytype() == 3*/){
                    lef = BigDecimal.ONE;
                }else{
                    lef = info.getStoreqty().subtract(item.getWeight());
                }
                if (lef.compareTo(BigDecimal.ZERO) > -1) {
                    Whinfo upinfo = new Whinfo();
                    upinfo.setGuid(info.getGuid());
                    upinfo.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                    whinfoService.updateWhinfo(upinfo);
                } else {
//                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                    result.put("msg", "noWhinfo");
//                    return result;
                    throw new CustomException("库存不足！");
                }
            } else {
//                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//                result.put("msg", "noWhinfo");
//                return result;
                if (sf.getAutoType() == 2){
                    //采收生成的订单，允许出现负库存
                    Whinfo whinfo = new Whinfo();
                    String whinfoGuid = IdUtils.fastSimpleUUID();
                    whinfo.setGuid(whinfoGuid);
                    whinfo.setStorermguid(item.getSrguid());
                    whinfo.setStorehguid(item.getShrguid());
                    whinfo.setProductid(item.getProductguid());
                    whinfo.setSpguid(item.getSpguid());
                    //生成负库存
                    whinfo.setStoreqty(item.getWeight().negate());
                    whinfo.setCreatedate(new Date());
                    whinfo.setOperatorid(entity.getOperatorid());
                    whinfo.setOrgguid(entity.getOrgguid());
                    whinfo.setStockunit(item.getStockunit());
                    whinfo.setStockunitid(item.getStockunitid());
                    //获取产品名称
                    Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                    whinfo.setProductname(product.getProductname());
                    whinfoService.insertWhinfo(whinfo);

                }else{
                    throw new CustomException("库存不足！");
                }
            }
            if (null != sf.getPlantformLoadDate()){
                syncWhinfoRecords(item, sf.getPlantformLoadDate());
            }
        }
//        result.put("msg", "success");
//        return result;
    }

    /**
     * 20240105 出库操作
     * @param whoutform         出库单主表信息
     * @param whoutformitems    出库单明细表信息
     * @param minusAllowed      是否允许出库后负库存
     * @param backDatedDate     倒退日日期，null表示按当前日期出库
     * @return                  为兼容老系统，返回出库总重量：如果物料的库存单位是库存单位的话（KG），则
     *                          返回以吨为单位的出库总重量
     */
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public BigDecimal whout(Whoutform whoutform, List<Whoutformitem> whoutformitems,boolean minusAllowed,Date backDatedDate) {
        //批量调用的时候可能会报错，需要处理
        //20240806 批量调用时必须在调用方处理好user信息
        SysUser user ;
        if(whoutform.getOperatorid()==null){
            user = SecurityUtils.getLoginUser().getUser();
        }else{
            user = sysUserMapper.selectUserByGuid(whoutform.getOperatorid());
        }
        BigDecimal result=BigDecimal.ZERO;
        // 生成编码
        whoutform.setWhoutcode(codeService.getCode("7"));

        Storeroom room = storeroomMapper.selectStoreroomByGuid(whoutform.getSrguid());
        String orgguid = room.getOrgguid();
        String orgname = room.getOrgname();
        whoutform.setOrgguid(orgguid);
        whoutform.setOrgname(orgname);

        whoutform.setOperatorid(user.getGuid());

        String guid = IdUtils.fastSimpleUUID();
        whoutform.setGuid(guid);

        if (null == backDatedDate){
            whoutform.setCreatetime(DateUtils.getNowDate());
        }else{
            whoutform.setCreatetime(backDatedDate);
        }

        if (StringUtils.isBlank(whoutform.getChannel())){
            whoutform.setChannel("internal");
        }
        whoutformMapper.insertWhoutform(whoutform);

        for (Whoutformitem item : whoutformitems) {
            item.setWhoutid(guid);

            item.setSrguid(whoutform.getSrguid());

            item.setOrgguid(orgguid);
            item.setOrgname(orgname);

            //获取出库明细物料信息
            Salesspecification spec = salesSpecificationService.selectSalesspecificationById(item.getSpguid());
            //出库明细表中物料出库单位=物料的库存单位
            item.setStockunitid(spec.getStockunitid());
            item.setStockunit(spec.getStockunit());

            //对物料单位、数量的转换处理
            //20240104 前台送上来的item中，必须包含该物料下单时的单位id:item.getSfunitid()
            processWhoutWeight(whoutform,item,spec);

            validate(whoutform,item);

            whoutform.setWeight(whoutform.getWeight()==null?item.getWeight():whoutform.getWeight().add(item.getWeight()));

            //当前物料出库数量转换为吨累加
            result = result.add(transToT(item.getWeight(),spec));

            item.setGuid(IdUtils.fastSimpleUUID());
            item.setCreateTime(DateUtils.getNowDate());
            item.setCreateBy(user.getUserId());
            whoutformitemMapper.insertWhoutformitem(item);

            // 更新库存信息
            Whinfo info = whinfoService.getWhinfo(orgguid, item.getProductguid(), item.getSrguid(), item.getShrguid(),
                    item.getSpguid());
            if (info != null) {
                //判断出库后库存剩余
                BigDecimal lef = info.getStoreqty().subtract(item.getWeight());

                if (lef.compareTo(BigDecimal.ZERO) < 0 && !minusAllowed) {
                    throw new CustomException("库存不足！");
                }
                Whinfo upinfo = new Whinfo();
                upinfo.setGuid(info.getGuid());
                upinfo.setStoreqty(info.getStoreqty().subtract(item.getWeight()));
                whinfoService.updateWhinfo(upinfo);
                //20240109 将物料出库时的库存成本价反馈给调用方
                item.setCostPrice(info.getPrice());
            } else {
                if (minusAllowed){
                    //采收生成的订单，允许出现负库存
                    Whinfo whinfo = new Whinfo();
                    String whinfoGuid = IdUtils.fastSimpleUUID();
                    whinfo.setGuid(whinfoGuid);
                    whinfo.setStorermguid(item.getSrguid());
                    whinfo.setStorehguid(item.getShrguid());
                    whinfo.setProductid(item.getProductguid());
                    whinfo.setSpguid(item.getSpguid());
                    //生成负库存
                    whinfo.setStoreqty(item.getWeight().negate());
                    whinfo.setCreatedate(new Date());
                    whinfo.setOperatorid(whoutform.getOperatorid());
                    whinfo.setOrgguid(whoutform.getOrgguid());
                    whinfo.setStockunit(item.getStockunit());
                    whinfo.setStockunitid(item.getStockunitid());
                    //获取产品名称
                    Productinfo product = productinfoMapper.selectProductinfoById(item.getProductguid());
                    whinfo.setProductname(product.getProductname());
                    whinfoService.insertWhinfo(whinfo);

                }else{
                    throw new CustomException("库存不足！");
                }
            }
            if (backDatedDate!=null){
                syncWhinfoRecords(item, backDatedDate);
            }
        }
        whoutform.setLbweight(whoutform.getWeight());

        //可能需要更新whoutform/whoutforitem
        updateWhoutform(whoutform);

        return result;
    }

    /**
     * 校验出库数据
     * @param whoutform   出库单主表信息
     * @param item        出库单详情
     */
    private void validate(Whoutform whoutform, Whoutformitem item) {
        if(StringUtils.isBlank(item.getOrgguid())){
            throw new CustomException("出库单库存组织不能为空！");
        }
        if(StringUtils.isBlank(item.getProductguid())){
            throw new CustomException("出库单产品ID不能为空！");
        }
        if(StringUtils.isBlank(item.getSpguid())){
            throw new CustomException("出库单物料ID不能为空！");
        }
        if(StringUtils.isBlank(item.getSrguid())){
            throw new CustomException("出库单库房ID不能为空！");
        }
        if(StringUtils.isBlank(item.getShrguid())){
            throw new CustomException("出库单库间ID不能为空！");
        }
    }

    /**
     * 当前物料出库数量转换为吨
     * @param weight  数量
     * @param spec    当前物料
     * @return        当前物料是重量单位的话，数量转换为吨,否则如果是数量单位，返回0
     */
    private BigDecimal transToT(BigDecimal weight, Salesspecification spec) {
        Stockunit stockunit = stockunitService.selectStockunitById(spec.getStockunitid());
        if(stockunit==null){
            throw new CustomException("物料库存单位获取异常"+spec.getStockunitid());
        }
        if(stockunit.getIsUnit()==1){
           return  weight.multiply(stockunit.getToT());
        }
        return BigDecimal.ZERO;
    }

    /**
     * 出库出库单明细表中的出库数量
     * @param whoutform    出库单主表信息
     * @param item         出库单明细表数据
     * @param spec         出库单明细表对应的物料信息
     */
    private void processWhoutWeight(Whoutform whoutform, Whoutformitem item, Salesspecification spec) {
        if(item.getSfunitid() == null){
            //如果没有传入业务单据的单位，默认为库存单位，不转换
            item.setBusinessUnitId(spec.getStockunitid());
            item.setBusinessUnitName(spec.getStockunit());
            item.setBusiunitTostockunitRate(BigDecimal.ONE);
            return;
        }
        if (item.getWeight() == null || BigDecimal.ZERO.compareTo(item.getWeight()) == 0){
            throw new CustomException(spec.getName() + "出库数量不能为0！");
        }
        BigDecimal rate = item.getBusiunitTostockunitRate();
        if(rate == null){
            //业务单据没有转换率，对于销售订单，获取物料表的销售单位转换率，其他订单，不转换
            if(whoutform.getOuttype()== WhoutformTypeEnums.SALE.getCode()){
                //salesspecification的netWeight的含义变更为销售单位转换率
                rate = spec.getNetweight();
                if(rate==null || BigDecimal.ZERO.compareTo(rate) == 0 ){
                    rate = stockunitService.getRate(spec.getSfunitid(),spec.getStockunitid());
                }
            }else{
                rate = BigDecimal.ONE;
            }
        }

        if(rate == null){
            throw new CustomException(spec.getName()+"库存单位转换异常！");
        }
        //出库数量转换为库存单位数量
        item.setWeight(item.getWeight().multiply(rate));
        item.setBusiunitTostockunitRate(rate);
        //赠送数量的单位转换
        if(item.getHandsel()!=null){
            item.setHandselweight(item.getHandsel().multiply(rate));
        }
        if (item.getPrice() != null){
            item.setStockUnitPrice(item.getPrice().divide(rate,6, BigDecimal.ROUND_HALF_UP));
        }
        if (item.getInnerPrice() != null){
            item.setInnerPrice(item.getInnerPrice().divide(rate,6, BigDecimal.ROUND_HALF_UP));
        }
    }


    private String updateSellform(Whoutform entity, String orderid, SysUser user, Long nodeid, BigDecimal weight,
                                  int loadcount, Sellform sf, List<Sellspitem> spitems, String fileIds, String opinion) {
        Storeroom room = storeroomMapper.selectStoreroomByGuid(sf.getStorermguid());
        Sellform sfo = new Sellform();
        sfo.setGuid(orderid);
        sfo.setLoadweight(weight);
        sfo.setLbweight(weight);
        sfo.setStrmId(room.getId());
        sfo.setStrmName(room.getName());
        sfo.setStoreOrgId(room.getOrgId());
        sfo.setStoreOrgName(room.getOrgname());
        sfo.setLoadcount(loadcount);
        // 套装的情况下，出库数量由套装+单品组成
        if (spitems.size() > 0 && entity.getLoadcount() != null) {
            sfo.setLoadcount(entity.getLoadcount());
        }
        sf.setPlatformId(sf.getStrmId());
        sf.setCode(sf.getSellcode());
        FlowResult result = flowProcessProxy.approval(nodeid, fileIds, opinion, sf
                , user);
        if (result.getMsg().equals(ResultParam.SUCCESS)) {
            sfo.setGuid(orderid);
            if (sf.getPaytype() == 4 || sf.getPaytype() == 5) {
                sfo.setSettletime(new Date());
            }
            sfo.setLoadDate(new Date());
            sfo.setStatus(result.getNextStat());
            sellformMapper.updateSellform(sfo);
            return "success";
        } else {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return result.getMsg();
        }
    }

    private List<Sellspitem> updateSellitems(String orderid, List<Whoutformitem> items, SysUser user, Integer settletype) {
        List<Sellspitem> spitems = sellspitemMapper.selectSellspitemListBySellguid(orderid);
        for (Whoutformitem item : items) {
            sellitemService.updatePI(item, user);
            // 更新套装出库件数
            if (spitems.size() > 0) {
                Sellitem si = sellitemMapper.selectSellitemById(item.getItemguid());
                for (Sellspitem spi : spitems) {
                    if (StringUtils.equalsIgnoreCase(spi.getGuid(), si.getSuitpackid())) {
                        spi.setLoadhandsel(item.getHandsel() == null ? 0 : item.getHandsel().intValue());
                        spi.setLoadcount(item.getLoadcount().intValue());
                        sellspitemMapper.updateSellspitem(spi);
                    }
                }

            }
            if (1 == settletype) {
                Sellitem sellitem = new Sellitem();
                sellitem.setGuid(item.getItemguid());
                sellitem.setLoadhandsel(item.getHandsel()==null ? 0:item.getHandsel().intValue());
                sellitem.setLoadweight(new BigDecimal(item.getLoadcount()));
                sellitem.setUpdateBy(user.getUserId());
                sellitem.setUpdateTime(DateUtils.getNowDate());
                sellitemService.updateSellitem(sellitem);
            }
        }
        return spitems;
    }

    /**
     * 暂时不处理物流
     * @param item
     * @param user
     */
    public void handleWlinfo(Wlinfoitem item, SysUser user) {
        /*Wlinfo wlinfo = wlinfoMapper.selectWlinfoById(item.getWlinfoid());
        Flowtempnode node = new Flowtempnode();
        node.setFlowtempid("16");
        node.setNodetype(55);
        node = nodeService.view(node);

        Map<String, String> results = nodeService.businessProcesss(node.getGuid(), null, wlinfo.getCode(), null,
                wlinfo.getDepartid(), "货品出库", wlinfo, null, user);
        if (results.get("msg").equals("success")) {
            Wlinfo wl = new Wlinfo();
            wl.setGuid(wlinfo.getGuid());
            if (StringUtils.isNotBlank(results.get("flownextstat"))) {
                wl.setStatus(Integer.parseInt(results.get("flownextstat")));
            }
            wlinfoService.update(wl);
        }*/
    }
}
